package com.sunlake.spring.main.common.model.pay.service.impl;

import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.sunlake.spring.main.common.model.pay.dto.PayRequestDTO;
import com.sunlake.spring.main.common.model.pay.mq.producer.PayMessageProducer;
import com.sunlake.spring.main.common.model.pay.service.PayService;
import com.sunlake.spring.main.config.AlipayConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author liuhanzhi49
 */
@Service
@Slf4j
public class PayServiceImpl implements PayService {

    @Autowired
    private AlipayConfig alipayConfig;

    @Autowired
    private PayMessageProducer payMessageProducer;

    /**
     * 创建支付宝客户端
     */
    private AlipayClient createAlipayClient() {
        return new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getPrivateKey(),
                "json",
                alipayConfig.getCharset(),
                alipayConfig.getPublicKey(),
                alipayConfig.getSignType()
        );
    }

    /**
     * 生成支付宝支付二维码
     */
    @Override
    public String generatePayQrCode(String subject, String body, String totalAmount, String timeoutExpress) throws AlipayApiException {
        // 创建支付宝客户端
        AlipayClient alipayClient = createAlipayClient();

        // 创建扫码支付请求模型
        AlipayTradePrecreateRequest payRequest = new AlipayTradePrecreateRequest();
        payRequest.setNotifyUrl(alipayConfig.getNotifyUrl());

        // 生成商户订单号
        String outTradeNo = "ORD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8);

        // 构建请求参数
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", outTradeNo);
        bizContent.set("total_amount", totalAmount);
        bizContent.set("subject", subject);
        bizContent.set("body", body);
        bizContent.set("timeout_express", timeoutExpress);

        payRequest.setBizContent(bizContent.toString());

        // 调用支付宝接口，发起预下单请求
        AlipayTradePrecreateResponse payResponse = alipayClient.execute(payRequest);

        if (payResponse.isSuccess()) {
            // 创建订单信息对象
            Map<String, Object> orderInfo = new HashMap<>();
            orderInfo.put("outTradeNo", outTradeNo);
            orderInfo.put("totalAmount", totalAmount);
            orderInfo.put("subject", subject);
            orderInfo.put("createTime", new Date());

            // 使用消息生产者发送订单创建消息
            payMessageProducer.sendOrderCreateMessage(orderInfo);

            log.info("生成支付宝支付二维码成功，订单号：{}", outTradeNo);
            return payResponse.getQrCode();
        } else {
            log.error("生成支付宝支付二维码失败：{}", payResponse.getMsg());
            throw new AlipayApiException(payResponse.getMsg());
        }
    }

    /**
     * 生成支付宝支付二维码（支持更灵活的参数）
     */
    @Override
    public String generatePayQrCode(PayRequestDTO payRequestDTO) throws AlipayApiException {
        // 创建支付宝客户端
        AlipayClient alipayClient = createAlipayClient();

        // 创建扫码支付请求模型
        AlipayTradePrecreateRequest payRequest = new AlipayTradePrecreateRequest();
        payRequest.setNotifyUrl(alipayConfig.getNotifyUrl());

        // 优先使用传入的outTradeNo（可能是rechargeNo），如果没有再生成
        String outTradeNo = payRequestDTO.getOutTradeNo();
        if (outTradeNo == null || outTradeNo.isEmpty()) {
            outTradeNo = "ORD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8);
        }

        // 构建请求参数
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", outTradeNo);
        bizContent.set("total_amount", payRequestDTO.getTotalAmount());
        bizContent.set("subject", payRequestDTO.getSubject());
        bizContent.set("body", payRequestDTO.getBody());
        bizContent.set("timeout_express", payRequestDTO.getTimeoutExpress() != null ? payRequestDTO.getTimeoutExpress() : "90m");

        payRequest.setBizContent(bizContent.toString());

        // 调用支付宝接口，发起预下单请求
        AlipayTradePrecreateResponse payResponse = alipayClient.execute(payRequest);

        if (payResponse.isSuccess()) {
            // 创建订单信息对象
            Map<String, Object> orderInfo = new HashMap<>();
            orderInfo.put("outTradeNo", outTradeNo);
            orderInfo.put("totalAmount", payRequestDTO.getTotalAmount());
            orderInfo.put("subject", payRequestDTO.getSubject());
            orderInfo.put("createTime", new Date());

            // 使用消息生产者发送订单创建消息
            payMessageProducer.sendOrderCreateMessage(orderInfo);

            log.info("生成支付宝支付二维码成功，订单号：{}", outTradeNo);
            return payResponse.getQrCode();
        } else {
            log.error("生成支付宝支付二维码失败：{}", payResponse.getMsg());
            throw new AlipayApiException(payResponse.getMsg());
        }
    }

    /**
     * 处理支付宝异步通知
     */
    @Override
    public boolean handlePayNotify(Map<String, String> params) {
        try {
            log.info("收到支付宝支付通知");

            // 提取关键参数
            String outTradeNo = params.get("out_trade_no");
            String tradeStatus = params.get("trade_status");
            String totalAmount = params.get("total_amount");
            String tradeNo = params.get("trade_no");

            // 创建支付结果消息
            Map<String, Object> payResult = new HashMap<>();
            payResult.put("outTradeNo", outTradeNo);
            payResult.put("tradeStatus", tradeStatus);
            payResult.put("totalAmount", totalAmount);
            payResult.put("transactionNo", tradeNo);
            payResult.put("notifyTime", new Date());

            // 使用消息生产者发送支付结果消息
            payMessageProducer.sendPayResultMessage(payResult);

            log.info("支付结果已发送到消息队列，订单号：{}", outTradeNo);
            return true;
        } catch (Exception e) {
            log.error("处理支付宝通知异常：", e);
            return false;
        }
    }

    /**
     * 查询支付宝订单支付状态
     */
    @Override
    public String queryTradeStatus(String outTradeNo) throws AlipayApiException {
        // 创建支付宝客户端
        AlipayClient alipayClient = createAlipayClient();

        // 创建查询请求
        AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();

        // 设置业务参数
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", outTradeNo);
        queryRequest.setBizContent(bizContent.toString());

        // 执行查询请求
        AlipayTradeQueryResponse queryResponse = alipayClient.execute(queryRequest);

        if (queryResponse.isSuccess()) {
            // 返回交易状态
            return queryResponse.getTradeStatus();
        } else {
            // 记录错误信息
            log.error("查询支付宝订单状态失败：{}，错误码：{}", queryResponse.getMsg(), queryResponse.getSubCode());
            // 如果是交易不存在的错误，返回PENDING状态而不是抛出异常
            if ("ACQ.TRADE_NOT_EXIST".equals(queryResponse.getSubCode())) {
                log.info("订单{}在支付宝中不存在，可能是尚未支付或已超时", outTradeNo);
                return "WAIT_BUYER_PAY";
                // 返回等待买家付款状态
            }
            // 其他错误仍然抛出异常
            throw new AlipayApiException(queryResponse.getMsg());
        }
    }
}